home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / GENetReleaseƒ / GETest / SynchTest.c < prev   
C/C++ Source or Header  |  1994-03-08  |  16KB  |  701 lines

  1. /*
  2.     SynchTest.c
  3.     
  4.     Test program for exploring relationship between number of objects, object move,
  5.     object update interval, and frame update interval
  6.     
  7.     1/29/94
  8.     
  9.     Al Evans
  10. */
  11.  
  12. #ifdef applec
  13. #ifndef PRELOAD
  14. #pragma load "::ToolKit.precompile"
  15. #define PRELOAD
  16. #endif
  17. #else
  18. #include <QDOffscreen.h>
  19. #endif
  20.  
  21. #include <Timer.h>
  22. #include <GestaltEqu.h>
  23.  
  24. #include "GUtilities.h"
  25. #include "GraphElements.h"
  26. #include "SynchGraphic.h"
  27. #include "Meter.h"
  28.  
  29.  
  30.  
  31. //Menu Commands
  32.  
  33. #define    rMenuBar                128        /* application's menu bar */
  34.  
  35. #define    mApple                    128        /* Apple menu */
  36. #define    iAbout                    1
  37.  
  38. #define    mFile                    129        /* File menu */
  39. #define    iQuit                    1
  40.  
  41. #define    mEdit                    130        /* Edit menu */
  42. #define    iUndo                    1
  43. #define    iCut                    3
  44. #define    iCopy                    4
  45. #define    iPaste                    5
  46. #define    iClear                    6
  47.  
  48. #define mSpecial                131
  49. #define iSetParams                1
  50. #define iMeter                    2
  51. #define iTiming                    3
  52.  
  53. #define    rAboutDialog    228        
  54. #define rUserAlert        129
  55. #define rPerfAlert        300
  56. #define rSetParamsDialog    135
  57.  
  58. //Resource numbers of graphic PICTs
  59. #define    rBkgPic 200
  60.  
  61. //Number of master pointer blocks needed
  62.  
  63. #define masterBlocksNeeded 10
  64.  
  65. //Globals
  66.  
  67. Boolean        gFinished;
  68. WindowPtr    gAnimWindow;
  69. Boolean        gSingleFrame = false;
  70. Boolean        gDoOne = false;
  71. Boolean        gMeterShown = true;
  72.  
  73. //Performance measurement
  74.  
  75. #define thirtySeconds 30L * 1000 * 1000        //µsec for timers -- never time out
  76.  
  77. TMTask    gTTimeTask, gATimeTask;
  78. unsigned long gTotalTime = 0, gAnimTime = 0;
  79.  
  80.  
  81. //Forward declarations
  82.  
  83. #ifdef applec
  84. extern void _DataInit();    //reference so that we can unload it
  85. #endif
  86.  
  87. Boolean Initialize( void );
  88. void Shutdown(void);
  89. void EventLoop( void );
  90.  
  91. main()
  92. {
  93. #ifdef applec
  94.     UnloadSeg((Ptr) _DataInit);
  95. #endif
  96.     
  97.     MaxApplZone();
  98.     if ( Initialize() )
  99.         EventLoop();
  100.     Shutdown();
  101. }
  102.  
  103.  
  104. //Initialization
  105.  
  106. Boolean AdequateSystem(void)
  107. {
  108.     OSErr        err;
  109.     long        response;
  110.     Boolean        ok;
  111.     
  112.     //We need 68020 or better
  113.     err = Gestalt(gestaltProcessorType, &response);
  114.     ok = (!err) & (response >= gestalt68020);
  115.     
  116.     //We need System 7 or later
  117.     err = Gestalt(gestaltSystemVersion, &response);
  118.     ok = (!err) & (((response & 0xFFFF) / 256) >= 7);
  119.     
  120.     //We need color QD & offscreen GWorlds
  121.     err = Gestalt(gestaltQuickdrawVersion, &response);
  122.     ok = ok & (!err) & (response >= gestalt32BitQD);
  123.     err = Gestalt(gestaltQuickdrawFeatures, &response);
  124.     ok = ok & (!err) & (response >= 3);         //hasColor & deep GWorlds
  125.     
  126.     return ok;
  127.     
  128. }
  129.  
  130. //Make window centered on main graphic device
  131. WindowPtr MakeWindow(short wHSize, short wVSize)
  132. {
  133.     GDHandle    mainDevice;
  134.     Rect        devRect;
  135.     short        hOffst, vOffst;
  136.     Rect        windRect;
  137.     
  138.     mainDevice = GetMainDevice();
  139.     devRect = (**mainDevice).gdRect;
  140.     hOffst = (devRect.right - devRect.left - wHSize) / 2;
  141.     if (hOffst < 0) hOffst = 0;
  142.     vOffst = (devRect.bottom - devRect.top - wVSize) / 2;
  143.     if (vOffst < 0 ) vOffst = 0;
  144.     windRect.left = hOffst;
  145.     windRect.right = hOffst + wHSize;
  146.     windRect.top = vOffst;
  147.     windRect.bottom = vOffst + wVSize; 
  148.     
  149.     return NewCWindow(nil, &windRect, "\pSynch Test", false, documentProc,
  150.                         (WindowPtr) -1L, false, 0L);
  151. }
  152.  
  153.  
  154. void DoNothing( void )
  155. {
  156. }
  157.  
  158. void InitPerformanceTiming(void)
  159. {
  160.     //Init Timers
  161.     gTTimeTask.tmAddr = (TimerProcPtr) DoNothing;
  162.     gTTimeTask.tmWakeUp = 0;
  163.     gTTimeTask.tmReserved = 0;
  164.     
  165.     gATimeTask.tmAddr =  (TimerProcPtr) DoNothing;
  166.     gATimeTask.tmWakeUp = 0;
  167.     gATimeTask.tmReserved = 0;
  168.     
  169. }
  170.  
  171. Boolean LoadBackground(GEWorldPtr world)
  172. {
  173.     GrafElPtr    bkg;
  174.     if (bkg = NewBasicPICT(world, 'BKG ', 1, rBkgPic, srcCopy, 0, 0))
  175.         return true;
  176.     return false;
  177. }
  178.  
  179. Boolean Initialize(void)
  180. {
  181.     Rect        animRect;
  182.     GEWorldPtr    animWorld;
  183.     
  184.     gFinished = false;
  185.     
  186.     InitSystem(masterBlocksNeeded);
  187.     
  188.     
  189.     if (!AdequateSystem()) {
  190.         TellUser("\pSorry, more powerful system required", 0);
  191.         return false;
  192.     }
  193.     if (!LoadMenus(rMenuBar)) {
  194.         TellUser("\pCould not load menus", 0);
  195.         return false;
  196.     }
  197.     
  198.     //DebugStr("\pInitializing...");
  199.     //Create window and install animation
  200.     if (gAnimWindow = MakeWindow(512, 364)){
  201.         animRect.left = 0;
  202.         animRect.right = 512;
  203.         animRect.top = 0;
  204.         animRect.bottom = 364;
  205.         if (animWorld = NewGEWorld((CWindowPtr) gAnimWindow, &animRect, nil))
  206.             SetWRefCon(gAnimWindow, (long) animWorld);
  207.         else {
  208.             TellUser("\pCould not install animation in window", 0);
  209.             return false;
  210.         }
  211.     }
  212.     else {
  213.         TellUser("\pCould not create window", 0);
  214.         return false;
  215.     }
  216.     
  217.     InitPerformanceTiming();
  218.     
  219.     //Load graphics
  220.     
  221.     if (!LoadBackground((GEWorldPtr) GetWRefCon(gAnimWindow))) {
  222.         TellUser("\pCould not load background", 0);
  223.         return false;
  224.     }
  225.     if (!InitObjectGraphics((GEWorldPtr) GetWRefCon(gAnimWindow))) {
  226.         TellUser("\pCould not load test graphic", 0);
  227.         return false;
  228.     }
  229.  
  230.     if (!LoadUsageMeterScene((GEWorldPtr) GetWRefCon(gAnimWindow))) {
  231.         TellUser("\pCould not load usage meter", 0);
  232.         return false;
  233.     }
  234.     //Reposition meter a little to the left
  235.     MoveElement((GEWorldPtr) GetWRefCon(gAnimWindow), meterBkgID, -100, 0);
  236.     
  237.     
  238.     //Turn animation on and show window
  239.     SetNumberOfObjects((GEWorldPtr) GetWRefCon(gAnimWindow), 4);
  240.     ActivateWorld((GEWorldPtr) GetWRefCon(gAnimWindow), true);
  241.     ShowWindow(gAnimWindow);
  242.     
  243. }
  244.  
  245.  
  246. void Shutdown(void)
  247. {
  248.     //Release system resources
  249.     
  250.     StopGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
  251.     ExitToShell();
  252. }
  253.  
  254.  
  255.  
  256. void RunMeterAnimation(short ms)
  257. {
  258.     static short    setting = 0;
  259.     
  260.     if (gMeterShown && (ms > 1)) {
  261.         if (ms == setting)
  262.             return;
  263.         if (ms > setting)
  264.             setting++;
  265.         else
  266.             if (ms < setting)
  267.                 setting--;
  268.         SetMeterReading((GEWorldPtr) GetWRefCon(gAnimWindow), 2 * setting);
  269.     }
  270.     
  271. }
  272.  
  273. void DisplayPerformance(long frames, long seconds)
  274. {
  275.     Str255 framesString, secondsString, fpsString;
  276.     long fps;
  277.     
  278.     NumToString(frames, framesString);
  279.     NumToString(seconds, secondsString);
  280.  
  281.     fps = (seconds > 0) ? frames / seconds : frames;
  282.     NumToString(fps, fpsString);
  283.  
  284.     ParamText(framesString, secondsString, fpsString, "\p");
  285.     NoteAlert(rPerfAlert, nil);
  286. }
  287.  
  288. void DoTimingLoop(void)
  289. {
  290.     long ticks;
  291.     short oObjUpdate;
  292.     unsigned long frames, seconds;
  293.     GEWorldPtr    world = (GEWorldPtr) GetWRefCon(gAnimWindow);
  294.     
  295.     oObjUpdate = GetUpdateInterval();
  296.     SetUpdateInterval(world, 1);
  297.     StartGETimer(world);
  298.     ticks = TickCount();
  299.     for (frames = 0; ((TickCount() - ticks) < (30 * 60)) && (!Button()); frames++) { 
  300.         DoWorldUpdate(world, false);
  301.     }
  302.     
  303.     seconds = ((TickCount() - ticks) / 60);
  304.     
  305.     DisplayPerformance(frames, seconds);
  306.     //SetUpdateInterval(world, oPIntrvl);
  307.     SetUpdateInterval(world, oObjUpdate);
  308.     
  309. }
  310.  
  311. //Dialog items
  312. #define    dItmNObj    4
  313. #define dItmMDist    6
  314. #define dItmSep        8
  315. #define dItmUpd        10
  316. #define dItmLinear    11
  317. #define dItmRandom    12
  318. #define dItmCollide    13
  319.  
  320. void DoSetParams( void )
  321. {
  322.  
  323.     DialogPtr     frDialog;
  324.     short        itemType;
  325.     Handle        item;
  326.     Rect        okRect;
  327.     Rect        itemRect;
  328.     short        itemHit;
  329.     Str255        tempStr;
  330.     ControlHandle    btnRandom, btnLinear, boxCollide;
  331.     
  332.     long        oNumObj, nNumObj;
  333.     long        oMoveDist, nMoveDist;
  334.     long        oSep, nSep;
  335.     long        oObjUpdate, nObjUpdate;
  336.     Boolean        oMovement, nMovement;    //linear (true) or random
  337.     Boolean        collision;                //if random motion, true == collision enabled
  338.     
  339.     frDialog = GetNewDialog(rSetParamsDialog, nil, (WindowPtr) -1L);
  340.     GetDItem(frDialog, ok, &itemType, &item, &okRect);
  341.     
  342.     //Present number of objects -> dialog
  343.     oNumObj = GetNumberOfObjects();
  344.     GetDItem(frDialog, dItmNObj, &itemType, &item, &itemRect);
  345.     NumToString(oNumObj, tempStr);
  346.     SetIText(item, tempStr);
  347.     
  348.     //Present move distance -> dialog
  349.     oMoveDist = GetMoveDistance();
  350.     GetDItem(frDialog, dItmMDist, &itemType, &item, &itemRect);
  351.     NumToString(oMoveDist, tempStr);
  352.     SetIText(item, tempStr);
  353.     
  354.     //Present object separation -> dialog
  355.     oSep = GetObjSeparation();
  356.     GetDItem(frDialog, dItmSep, &itemType, &item, &itemRect);
  357.     NumToString(oSep, tempStr);
  358.     SetIText(item, tempStr);
  359.     
  360.     //Present object update interval -> dialog
  361.     oObjUpdate = GetUpdateInterval();
  362.     GetDItem(frDialog, dItmUpd, &itemType, &item, &itemRect);
  363.     NumToString(oObjUpdate, tempStr);
  364.     SetIText(item, tempStr);
  365.     
  366.     //Get radio buttons, present object motion -> dialog
  367.     oMovement = MotionIsLinear();
  368.     nMovement = oMovement;
  369.     GetDItem(frDialog, dItmLinear,  &itemType, (Handle *) &btnLinear, &itemRect);
  370.     GetDItem(frDialog, dItmRandom,  &itemType, (Handle *) &btnRandom, &itemRect);
  371.     GetDItem(frDialog, dItmCollide, &itemType, (Handle *) &boxCollide, &itemRect);
  372.     SetCtlValue(btnLinear, oMovement?1:0);
  373.     SetCtlValue(btnRandom, oMovement?0:1);
  374.     collision = ObjCollisionActive();
  375.     HiliteControl(boxCollide, oMovement?255:0);
  376.     SetCtlValue(boxCollide, collision?1:0);
  377.     
  378.     //Do OK button
  379.     InsetRect(&okRect, -4, -4);
  380.     ShowWindow(frDialog);
  381.     SetPort( (GrafPtr) frDialog);
  382.     PenSize(3, 3);
  383.     FrameRoundRect(&okRect, 16, 16);
  384.     
  385.     SelIText(frDialog, dItmNObj, 0, 32767);
  386.     do {
  387.         ModalDialog(nil, &itemHit);
  388.         switch (itemHit) {
  389.             case dItmLinear:
  390.                 nMovement = true;
  391.                 SetCtlValue(btnLinear, 1);
  392.                 SetCtlValue(btnRandom, 0);
  393.                 HiliteControl(boxCollide, 255);
  394.                 break;
  395.             case dItmRandom:
  396.                 nMovement = false;
  397.                 SetCtlValue(btnLinear, 0);
  398.                 SetCtlValue(btnRandom, 1);
  399.                 HiliteControl(boxCollide, 0);
  400.                 break;
  401.             case dItmCollide:
  402.                 SetCtlValue(boxCollide, (GetCtlValue(boxCollide) ==1)?0:1);
  403.                 break;
  404.         }
  405.     } while ( (itemHit != ok) && (itemHit != cancel) );
  406.     
  407.     if (itemHit == ok) {
  408.         //Get new values
  409.         GetDItem(frDialog, dItmNObj, &itemType, &item, &itemRect);
  410.         GetIText(item, tempStr);
  411.         StringToNum(tempStr, &nNumObj);
  412.         GetDItem(frDialog, dItmMDist, &itemType, &item, &itemRect);
  413.         GetIText(item, tempStr);
  414.         StringToNum(tempStr, &nMoveDist);
  415.         GetDItem(frDialog, dItmSep, &itemType, &item, &itemRect);
  416.         GetIText(item, tempStr);
  417.         StringToNum(tempStr, &nSep);
  418.         GetDItem(frDialog, dItmUpd, &itemType, &item, &itemRect);
  419.         GetIText(item, tempStr);
  420.         StringToNum(tempStr, &nObjUpdate);
  421.         if (nMoveDist != oMoveDist)
  422.             SetMoveDistance((GEWorldPtr) GetWRefCon(gAnimWindow), nMoveDist);
  423.         if (nSep != oSep)
  424.             SetObjSeparation((GEWorldPtr) GetWRefCon(gAnimWindow), nSep);
  425.         if (nObjUpdate != oObjUpdate)
  426.             SetUpdateInterval((GEWorldPtr) GetWRefCon(gAnimWindow), nObjUpdate);
  427.         if (oMovement != nMovement)
  428.             SetObjMotionLinear(nMovement);
  429.         if ((nNumObj != oNumObj) || (nSep != oSep) || (oMovement != nMovement))
  430.             SetNumberOfObjects((GEWorldPtr) GetWRefCon(gAnimWindow), nNumObj);
  431.         if (!nMovement) {
  432.             collision = (GetCtlValue(boxCollide) == 1)?true:false;
  433.             SetObjCollision((GEWorldPtr) GetWRefCon(gAnimWindow), collision);
  434.         }
  435.     }
  436.     DisposDialog(frDialog);
  437. }
  438.  
  439. pascal Boolean AboutFilter(DialogPtr dialog, EventRecord *event, short *item)
  440. {
  441. #pragma unused (dialog)
  442.     DoWorldUpdate((GEWorldPtr) GetWRefCon(gAnimWindow), false);
  443.     if ((event->what == mouseDown) || (event->what == keyDown)) {
  444.         *item = ok;
  445.         return true;
  446.     }
  447.     else return false;
  448. }
  449.  
  450. void DoAboutBox(void)
  451. {
  452.     DialogPtr    aboutDialog;
  453.     short        itemHit;
  454.     
  455.     aboutDialog = GetNewDialog(rAboutDialog, nil, (WindowPtr) -1L);
  456.     ModalDialog(AboutFilter, &itemHit);
  457.     DisposDialog(aboutDialog);
  458. }
  459.  
  460. //Event Handling
  461.  
  462. void EventLoop( void )
  463. {
  464.     Boolean        gotEvent;
  465.     EventRecord    event;
  466.     
  467.     void DoEvent (EventRecord *event);
  468.     void AdjustCursor( void);
  469.     
  470.     do {
  471.         InsTime( (QElemPtr) &gTTimeTask);
  472.         InsTime( (QElemPtr) &gATimeTask);
  473.         PrimeTime( (QElemPtr) &gTTimeTask, -thirtySeconds);
  474.         if (!gSingleFrame || gDoOne) {
  475.             PrimeTime( (QElemPtr) &gATimeTask, -thirtySeconds);
  476.             
  477.             DoWorldUpdate((GEWorldPtr) GetWRefCon(gAnimWindow), false);
  478.             
  479.             RmvTime( (QElemPtr) &gATimeTask);
  480.             gAnimTime = (thirtySeconds + gATimeTask.tmCount) / 1000;
  481.             gDoOne = false;
  482.         }
  483.         AdjustCursor();
  484.         if (gotEvent = WaitNextEvent(everyEvent, &event, 0L, nil)) 
  485.             DoEvent(&event);
  486.         RmvTime( (QElemPtr) &gTTimeTask);
  487.         gTotalTime = (thirtySeconds + gTTimeTask.tmCount) / 1000; //milliseconds
  488.         RunMeterAnimation(gAnimTime);
  489.         
  490.     } while (!gFinished);
  491. }
  492.  
  493. void DoEvent (EventRecord *event)
  494. {
  495.     short        part;
  496.     WindowPtr    window;
  497.     char        key;
  498.     
  499.     //Prototypes
  500.     void AdjustMenus( void );
  501.     void DoMenuCommand(long menuResult);
  502.     void DoActivate(WindowPtr window, Boolean becomingActive);
  503.     void DoUpdate(WindowPtr window);
  504.     
  505.     switch ( event->what ) {
  506.         case mouseDown:
  507.             part = FindWindow(event->where, &window);
  508.             switch ( part ) {
  509.                 case inMenuBar:
  510.                     StopGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
  511.                     AdjustMenus();
  512.                     DoMenuCommand(MenuSelect(event->where));
  513.                     StartGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
  514.                     break;
  515.                 case inSysWindow:
  516.                     SystemClick(event, window);
  517.                     break;
  518.                 case inContent:
  519.                     if ( window != FrontWindow() ) 
  520.                         SelectWindow(window);
  521.                     if (MouseDownInSensor((GEWorldPtr) GetWRefCon(gAnimWindow), event->where))
  522.                         ;;
  523.                     break;
  524.                 case inDrag:
  525.                     DragWindow(window, event->where, &qd.screenBits.bounds);
  526.                     break;
  527.             }
  528.             break;
  529.         case keyDown:
  530.             key = event->message & charCodeMask;
  531.             if ( event->modifiers & cmdKey ) {
  532.                 StopGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
  533.                 AdjustMenus();
  534.                 DoMenuCommand(MenuKey(key));
  535.                 StartGETimer((GEWorldPtr) GetWRefCon(gAnimWindow));
  536.             }
  537.             else {
  538.                 switch (key) {
  539.                     case 'U':
  540.                     case 'u':
  541.                         MoveGEWorld((GEWorldPtr) GetWRefCon(gAnimWindow), 0, -50);
  542.                         break;
  543.                     case 'D':
  544.                     case 'd':
  545.                         MoveGEWorld((GEWorldPtr) GetWRefCon(gAnimWindow), 0, 50);
  546.                         break;
  547.                     case 'R':
  548.                     case 'r':
  549.                         MoveGEWorld((GEWorldPtr) GetWRefCon(gAnimWindow), 50, 0);
  550.                         break;
  551.                     case 'L':
  552.                     case 'l':
  553.                         MoveGEWorld((GEWorldPtr) GetWRefCon(gAnimWindow), -50, 0);
  554.                         break;
  555.                 }
  556.             }
  557.             gDoOne = true;
  558.             break;
  559.         case activateEvt:
  560.             DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
  561.             break;
  562.         case updateEvt:
  563.             DoUpdate((WindowPtr) event->message);
  564.             break;
  565.         case osEvt:
  566.             switch ((event->message >> 24) & 0x0FF) {
  567.                 case suspendResumeMessage:
  568.                     gInBackground = (event->message & resumeFlag) == 0;
  569.                     DoActivate(FrontWindow(), !gInBackground);
  570.                     break;
  571.             }
  572.             break;
  573.         }
  574. }
  575.  
  576. void DoActivate(WindowPtr window, Boolean becomingActive)
  577. {
  578. #pragma unused (window)
  579. #pragma unused (becomingActive)
  580.     //Could start and stop animation here
  581. }
  582.  
  583.  
  584. void DoUpdate(WindowPtr window)
  585. {
  586.     Rect geRect;
  587.     GEWorldPtr geWorld;
  588.  
  589.     if (window == gAnimWindow)
  590.     {
  591.         SetPort( (GrafPtr) window );
  592.         //Protect GEWorld rect before updating window, since we will draw it
  593.         geWorld = (GEWorldPtr) GetWRefCon(gAnimWindow);
  594.         geRect = geWorld->animationRect;
  595.         RectOffset(&geRect, geWorld->worldFocus.h, geWorld->worldFocus.v);
  596.         ValidRect(&geRect);
  597.         
  598.         BeginUpdate(window);
  599.             FillRgn(((GrafPtr) window)->visRgn, qd.gray);
  600.         EndUpdate(window);
  601.         
  602.         DoWorldUpdate((GEWorldPtr) GetWRefCon(gAnimWindow), true);
  603.     }
  604. }
  605.  
  606. void AdjustMenus( void )
  607. {
  608.     WindowPtr    window;
  609.     MenuHandle    menu;
  610.     
  611.     window = FrontWindow();
  612.     
  613.     menu = GetMHandle(mFile);
  614.     EnableItem(menu, iQuit);
  615.  
  616.     menu = GetMHandle(mEdit);
  617.     if (window = gAnimWindow) {
  618.         DisableItem(menu, iUndo);
  619.         DisableItem(menu, iCut);
  620.         DisableItem(menu, iCopy);
  621.         DisableItem(menu, iClear);
  622.         DisableItem(menu, iPaste);
  623.     }
  624.     else {
  625.         EnableItem(menu, iUndo);
  626.         EnableItem(menu, iCut);
  627.         EnableItem(menu, iCopy);
  628.         EnableItem(menu, iClear);
  629.         EnableItem(menu, iPaste);
  630.     }
  631.     menu = GetMHandle(mSpecial);
  632.     //Set up special items!
  633.     EnableItem(menu, iSetParams);
  634.     EnableItem(menu, iMeter);
  635.     CheckItem(menu, iMeter, gMeterShown);
  636.     EnableItem(menu, iTiming);
  637. }
  638.  
  639. void DoMenuCommand(long menuResult)
  640. {
  641.     short        menuID;
  642.     short        menuItem;
  643.     Str255        daName;
  644.     short        daRefNum;
  645.  
  646.     menuID = HiWord(menuResult);
  647.     menuItem = LoWord(menuResult);
  648.     switch ( menuID ) {
  649.         case mApple:
  650.             switch ( menuItem ) {
  651.                 case iAbout:
  652.                     DoAboutBox();
  653.                     break;
  654.                 default:            /* all other items in this menu are DAs */
  655.                     GetItem(GetMHandle(mApple), menuItem, daName);
  656.                     daRefNum = OpenDeskAcc(daName);
  657.                     break;
  658.             }
  659.             break;
  660.         case mFile:
  661.             if (menuItem == iQuit)
  662.                 gFinished = true;
  663.             break;
  664.         case mEdit:
  665.             (void) SystemEdit(menuItem-1);
  666.             break;
  667.         case mSpecial:
  668.             //Add special items
  669.             switch ( menuItem ) {
  670.                 case iSetParams:
  671.                     DoSetParams();
  672.                     break;
  673.                 case iMeter:
  674.                     gMeterShown = !gMeterShown;
  675.                     ShowElement((GEWorldPtr) GetWRefCon(gAnimWindow), meterBkgID, gMeterShown);
  676.                     ShowElement((GEWorldPtr) GetWRefCon(gAnimWindow), meterIndID, gMeterShown);
  677.                     break;
  678.                 case iTiming:
  679.                     DoTimingLoop();
  680.                     break;
  681.             }
  682.             break;
  683.     }
  684.     HiliteMenu(0);
  685. }
  686.  
  687. //Utility routines
  688.  
  689.  
  690. void AdjustCursor( void )
  691. {
  692.     WindowPtr    window;
  693.     
  694.     window = FrontWindow();
  695.     
  696.     if ( (window == gAnimWindow) && (!gInBackground) ) {
  697.         SetCursor(&qd.arrow);
  698.     }
  699. }
  700.  
  701.